using UnityEngine;

namespace Com.LuisPedroFonseca.ProCamera2D
{
	public class ProCamera2DPixelPerfect : BasePC2D, IPositionOverrider
	{
		public static string ExtensionName = "Pixel Perfect";

		public float PixelsPerUnit = 32f;

		public bool ViewportAutoScale = true;

		public Vector2 TargetViewportSizeInPixels = new Vector2(80f, 50f);

		[Range(1f, 32f)]
		public int Zoom = 1;

		public bool SnapMovementToGrid;

		public bool SnapCameraToGrid = true;

		public bool DrawGrid;

		public Color GridColor = new Color(1f, 0f, 0f, 0.1f);

		public float GridDensity;

		private float _pixelStep = -1f;

		private float _viewportScale;

		private Transform _parent;

		private int _poOrder = 2000;

		public float PixelStep => _pixelStep;

		public int POOrder
		{
			get
			{
				return _poOrder;
			}
			set
			{
				_poOrder = value;
			}
		}

		protected override void Awake()
		{
			base.Awake();
			if (!ProCamera2D.GameCamera.orthographic)
			{
				base.enabled = false;
				return;
			}
			ResizeCameraToPixelPerfect();
			ProCamera2D.AddPositionOverrider(this);
		}

		public Vector3 OverridePosition(float deltaTime, Vector3 originalPosition)
		{
			if (!base.enabled)
			{
				return originalPosition;
			}
			_parent = _transform.parent;
			if (_parent != null && _parent.position != Vector3.zero)
			{
				_parent.position = VectorHVD(Utils.AlignToGrid(Vector3H(_parent.position), _pixelStep), Utils.AlignToGrid(Vector3V(_parent.position), _pixelStep), Vector3D(_parent.position));
			}
			return VectorHVD(Utils.AlignToGrid(Vector3H(originalPosition), _pixelStep), Utils.AlignToGrid(Vector3V(originalPosition), _pixelStep), Vector3D(originalPosition));
		}

		public void ResizeCameraToPixelPerfect()
		{
			_viewportScale = CalculateViewportScale();
			CalculatePixelStep(_viewportScale);
			float newSize = (float)ProCamera2D.GameCamera.pixelHeight * 0.5f * (1f / PixelsPerUnit) / ((float)Zoom * _viewportScale);
			ProCamera2D.UpdateScreenSize(newSize);
		}

		public float CalculateViewportScale()
		{
			if (!ViewportAutoScale)
			{
				return 1f;
			}
			float num = (float)ProCamera2D.GameCamera.pixelWidth / TargetViewportSizeInPixels.x;
			float num2 = (float)ProCamera2D.GameCamera.pixelHeight / TargetViewportSizeInPixels.y;
			float f = (num > num2) ? num2 : num;
			f = Mathf.FloorToInt(f);
			if (f < 1f)
			{
				f = 1f;
			}
			return f;
		}

		private void CalculatePixelStep(float viewportScale)
		{
			_pixelStep = (SnapMovementToGrid ? (1f / PixelsPerUnit) : (1f / (PixelsPerUnit * viewportScale * (float)Zoom)));
		}

		private void AlignPositionToPixelPerfect()
		{
			float gridSize = _pixelStep;
			if (SnapMovementToGrid && !SnapCameraToGrid)
			{
				gridSize = 1f / (PixelsPerUnit * _viewportScale * (float)Zoom);
			}
			_parent = _transform.parent;
			if (_parent != null && _parent.position != Vector3.zero)
			{
				_parent.position = VectorHVD(Utils.AlignToGrid(Vector3H(_parent.position), gridSize), Utils.AlignToGrid(Vector3V(_parent.position), gridSize), Vector3D(_parent.position));
			}
			_transform.localPosition = VectorHVD(Utils.AlignToGrid(Vector3H(_transform.localPosition), gridSize), Utils.AlignToGrid(Vector3V(_transform.localPosition), gridSize), Vector3D(_transform.localPosition));
		}
	}
}
